Cartography Toolbox:
Waterlining Tool and Polygon Boundary Symbology Tool
Developed by:
Andrew Gibbs, Tony Le Donne, John Cortenbach and Camille Borrowdale
All credits go to original developers unless otherwise stated.
Python Version: 3.6.1
1.0 Introduction
The this toolbox contains two cartographically-focused tools that can be used to improve the artistic qualities of maps made within ArcGIS Pro. The tools include:
- Coastal vignettes are graphic representations of the interface between land and water. Vignettes can be utilized to depict land in a fashion that appears to gradually fade into water, representing shallow areas near shore transitioning into deepening water with a expanding sequence of corresponding shape outlines.
-The second tool, pertaining to inner/outer polygon boundary symbology simplifies the methodology with which a user can symbolize the interface boundary between adjacent shapefiles using two separate symbolized boundaries.
2.0 Toolbox Details
2.1 System and Software Requirements
Compatible Operating Systems
Compatible Software
Required Data Format
2.2 Limitations
2.3 Installing the Toolbox
2.4 Un-installing the Toolbox
3.0 Waterlining Tool
3.1 Tool Description
A tool used in ArcGIS Pro that creates multiple buffer outlines around a shapefile polygon using user-defined parameters. This tool assists in the cartographic process of creating thematic maps.
3.2 Using the Waterlining Tool
1. Workspace: User-defined shapefile
2. Output Feature Class: User-defined workspace of output destination
3. Buffer Distance: User input, amount will on geographic size of shapefile
4. Units: User input, dependent on shapefile
5. Inside or Outside: User Input, dependent on user-desired symbolization.
The following headings and subsections pertain to the Python foundation inside the tool itself:
3.3 Imports
import arcpy # include the ArcGIS library
import sys # include the system library to access the number of parameters
import math
import os
3.4 Functions
The waterlining functionality below is defined along with the parameters of the user-specified initial buffer distance and requested number of buffers. The output creates a series of buffers, whether inside or outside of the polygon itself, increasing exponentially with each successive buffer. In order to achieve this, we need to filter out each channel in the image using ArcGIS Pro Toolbox.
"""
* MyPrint
* Mini function to send the print messages to the right output
* Created by Jim Graham
*
* Input:
* - Message - string to be printed
*
* Output:
* - The message on either Wing Debug I/O or ArcGIS Pro Window
"""
def MyPrint(Message):
if (len(sys.argv)>1): # if running in a tool, print into ArcGIS
arcpy.AddMessage(Message)
else: # else print to Debug I/O
print(Message)
"""
* Vignette
* Complete buffer analysis using user-defined parameters, which creates multiple buffers, merges the buffers, and deletes the individual buffers.
*
* Input:
* - PolygonClassification - Specifies if the input feature layer is land or water, so the water lining displays on the proper side
* - InitialBufferDistance - Sets the distance to the initial buffer created, which is also the minimum distance subsequent buffers
* - NumberOfBuffers - Sets the total number of buffers to be created and then merged together
* - OutlineExpansionFactor - Value that increases the distance between buffers over iterations of buffer creations, beginning with the initial buffer distance and increasing
*
* Output:
* - A new feature layer shapefile that represents the water lining of the input feature layer.
"""
def Vignette (PolygonClassification, InitialBufferDistance, NumberOfBuffers):
count=1
# This allows us to run the script repeatedly without deleting the intermdiate files
arcpy.env.overwriteOutput=False
# Create a search cursor based on the shapefile
SearchCursor = arcpy.SearchCursor(InputFeatureLayer)
# Creates buffers outside of the input feature layer for coastal waterlining
if (PolygonClassification == "Land"):
for x in range(0, NumberOfBuffers):
# formula to calculate intervals between lines. is negative for Arc buffering inside polygon
distance = (InitialBufferDistance*math.exp(OutlineExpansionFactor*count)) - InitialBufferDistance
# same formula as above but positive for adding to attribute table.
distancePos = (InitialBufferDistance*math.exp(OutlineExpansionFactor*count)) - InitialBufferDistance
# Creates a buffer using the InitialBufferDistance, NumberOfBuffers, and OutlineExpansionFactor parameters and the input feature layer
arcpy.Buffer_analysis(InputFeatureLayer, "Buffer_" + OutputFeatureName + str(count) + ".shp", distance,"OUTSIDE_ONLY","ROUND","ALL")
# Creates a new field with the buffer distance and calculates the value
arcpy.AddField_management("Buffer_"+OutputFeatureName+str(count)+".shp", "bufferDist", "FLOAT")
arcpy.CalculateField_management("Buffer_"+OutputFeatureName+str(count)+".shp", "bufferDist", distancePos, "PYTHON_9.3")
count = count + 1
# Creates buffers inside of the input feature layer for water body waterlining
elif (PolygonClassification == "Water"):
for x in range(0, NumberOfBuffers):
# formula to calculate intervals between lines. is negative for Arc buffering inside polygon
distance = -(InitialBufferDistance*math.exp(OutlineExpansionFactor*count)) + InitialBufferDistance
# same formula as above but positive for adding to attribute table.
distancePos = (InitialBufferDistance*math.exp(OutlineExpansionFactor*count)) + InitialBufferDistance
# Creates a buffer using the InitialBufferDistance, NumberOfBuffers, and OutlineExpansionFactor parameters and the input feature layer
arcpy.Buffer_analysis(InputFeatureLayer, "Buffer_" + OutputFeatureName + str(count) + ".shp", distance,"OUTSIDE_ONLY","ROUND","ALL")
# Creates a new field with the buffer distance and calculates the value
arcpy.AddField_management("Buffer_"+OutputFeatureName+str(count)+".shp", "bufferDist", "FLOAT")
arcpy.CalculateField_management("Buffer_"+OutputFeatureName+str(count)+".shp", "bufferDist", distancePos, "PYTHON_9.3")
count = count + 1
################################################################# end functions
# Set up variables
# Setup default parameters and then get the parameters from the argument list if we are running as a tool in ArcMap.
OutputWorkspace = "C:/temp/Vignette"
InputFeatureLayer = "C:/temp/Vignette/Lake_Tahoe_NAD83_UTM_Zone_10.shp"
OutputFeatureName = "Test"
PolygonClassification = "water"
InitialBufferDistance = 700 # in meters
NumberOfBuffers = 20
OutlineExpansionFactor = 0.1
if (len(sys.argv)>1): # if running in a tool, get the parameters from arc
InputFeatureLayer = arcpy.GetParameterAsText(0) # input feature class
OutputWorkspace = arcpy.GetParameterAsText(1) # working directory
OutputFeatureName = arcpy.GetParameterAsText(2) # string for output file name
PolygonClassification = arcpy.GetParameterAsText(3) # string 'land' or 'water'
InitialBufferDistance = arcpy.GetParameter(4) #long int for increments
NumberOfBuffers = arcpy.GetParameter(5) #long int to exponentially increase for number of NumberOfBuffers
OutlineExpansionFactor = arcpy.GetParameter(6) #double
# Print the parameters for debugging
MyPrint("InputFeatureLayer: " + InputFeatureLayer)
MyPrint("OutputWorkspace: " + OutputWorkspace)
MyPrint("OutputFeatureName: " + OutputFeatureName)
MyPrint("PolygonClassification: " + PolygonClassification)
MyPrint("InitialBufferDistance: " + format(InitialBufferDistance))
MyPrint("NumberOfBuffers: " + format(NumberOfBuffers))
MyPrint("OutlineExpansionFactor: " + format(OutlineExpansionFactor))
3.5 Main Code
# This allows us to run the script repeatedly without deleting the intermediate files
arcpy.env.overwriteOutput = False
#set Workspace
arcpy.env.workspace = OutputWorkspace
# print processing step to screen
MyPrint("Running Vignette function: Creating buffers based on PolygonClassification, InitialBufferDistance, OutlineExpansionFactor, and NumberOfBuffers...")
# runs the vignette function
Vignette(PolygonClassification, InitialBufferDistance, NumberOfBuffers)
# print processing step to screen
MyPrint("Vignette done.")
# print processing step to screen
MyPrint("Merging buffers...")
# Creates empty list to load individual buffer files
FClassesList = []
i = 0
# appends individual buffer files into the FClassesList
fcs = arcpy.ListFeatureClasses("Buffer_*")
for fc in fcs:
FClassesList.append(fc)
i=i+1
# merges all elements of the FClassesList list into one file
arcpy.Merge_management(FClassesList, OutputFeatureName)
# print processing step to screen
MyPrint("Merging buffers done.")
# print processing step to screen
MyPrint("Deleting individual buffer feature classes...")
# Deletes individual buffers used in vignette tool
for feature in FClassesList:
arcpy.Delete_management(feature)
# print processing step to screen
MyPrint("Deleting individual buffer feature classes done.")
# print processing step to screen
MyPrint("Finished creating water lines!")
###################################################### end main code
4.0 Polygon Boundary Symbology Tool
4.1 Tool Description
The Polygon Boundary Symbology tool allows the user to modify the boundary outline of a polygon on either the inside or the outside of the polygon boundary.
4.2 Using the Tool
1. Input Features: User-defined shapefile
2. Output Feature Class: User-defined workspace of output destination
3. Buffer Distance: User input; amount will vary with the geographic extent of shapefile
4. Units: User input, dependent on shapefile
5. Inside or Outside: User Input; dependent upon user-desired symbolization.
The following headings and subsections pertain to the Python foundation inside the tool itself:
4.3 Library Imports
import arcpy # include the ArcGIS library
import sys # include the system library to access the number of parameters
4.4 Functions
def MyPrint(Message):
if (len(sys.argv)>1): # if running in a tool, print into ArcGIS
arcpy.AddMessage(Message)
else: # else print to Debug I/O
print(Message)
##################################################################
# Setup default parameters and then get the parameters from the argument
# list if we are running as a tool in ArcMap.
##################################################################
#Python script for quickly creating an inner polygon outline in ArcGIS Pro.
#Set up for use in an Arc toolbox.
InputPath = "C:\\temp\\lower48.shp" # define input file path
OutputPath = "C:\\temp\\lower48inside.shp" # name of output file
BufferDistance = "20 Miles" #floating point buffer distance input amount
Choice = "Inside"
if (len(sys.argv)>1): # if running in a tool, get the parameters from ArcGIS Pro
InputPath = arcpy.GetParameterAsText(0)
OutputPath = arcpy.GetParameterAsText(1)
BufferDistance = arcpy.GetParameterAsText(2)
Choice = arcpy.GetParameterAsText(3)
# Print the parameters for debugging
MyPrint("InputPath: "+InputPath)
MyPrint("OutputPath: "+OutputPath)
arcpy.AddMessage("Creating polygon boundary symbology based on user inputs...")
4.4 Main Code
arcpy.env.overwriteOutput=False
if (Choice == "Inside"):
(Notes) The first line of the above code ensures that the script can run repeatedly without overwriting intermediate files. The following line is based on if the user chooses to draw the boundary on the inside and if so, a message is printed marking the start of processing, then the next line creates a buffer based upon the user-specified shapefile and subsequently draws a stroke inside the boundary. Lastly, a message is printed to notify the user once the buffering has finished.
print("Beginning processing...")
#Complete analysis using user-defined parameters
arcpy.analysis.Buffer(InputPath, OutputPath, "-"+BufferDistance, "OUTSIDE_ONLY", "ROUND", "NONE", None, "PLANAR")
arcpy.AddMessage("Completed Inner Boundary Outline.")
elif (Choice == "Outside"):
print("Beginning processing...")
#Complete analysis using user-defined parameters
arcpy.analysis.Buffer(InputPath, OutputPath, BufferDistance, "OUTSIDE_ONLY", "ROUND", "NONE", None, "PLANAR")
arcpy.AddMessage("Completed Outer Boundary Outline.")
(Notes) The beginning of this block of code is an ‘else if’ statement that prompts the code to continue if the user chooses the ‘outside’ stroke option. Then a buffer is created just as in the previous ‘inside’ code does, but rather the stroke is drawn on the outside. Lastly, a message is printed to notify the user once the buffering has finished.
4.5 Example Applications
5.0 Troubleshooting and Contact Information
If there are any problems or concerns with this toolset, feel free to contact the following:
Contacts
Jim Graham: James.Graham@humboldt.edu
Amy Rock: Amy.Rock@humboldt.edu